# this code is in python3
import sys
from Workflow import Workflow
from xmlrpc.server import SimpleXMLRPCServer
class WorkflowFunctions:
    active_workflows = {}
    completed_workflows = {}      
    def get_names_of_running_workflows(self):
        # returns [{'workflow_name':'test.txt', 'status':'done'}, {'workflow_name':'glass_reception.txt', 'status':'done'}]
        r = []
        for workflow_key in self.active_workflows:
            workflow = self.active_workflows[workflow_key]
            component, values = self.active_workflows[workflow_key].q[0]
            if 'status' in values.keys():
                status = values['status']
            else:
                status = 'no status'
            if 'input' in values.keys():
                input = values['input']
            else:
                input = 'input not requested'
            r.append({'workflow_name':workflow_key, 'status':status, 'input':input})
        return r
      
      
    def get_workflow_status(self, workflow_name):
        return "hello"
      
      
    def push_data_into_current_step(self, workflow_name, key, key_data):
        self.active_workflows[workflow_name].push_data_into_current_step(key, key_data)
        return 0
         
         
    def reactivate_completed_workflow(self, workflow_namedate_key, step_num):
        self.active_workflows[workflow_namedate_key] = self.completed_workflows[workflow_namedate_key]
        self.active_workflows[workflow_namedate_key].restore_workflow_state_to_step_num(step_num)
        return 123
         
         
    def get_list_of_completed_workflows(self):
        # returns [{'workflow_name':'test.txt', 'status':'done'}, {'workflow_name':'glass_reception.txt', 'status':'done'}]
        r = []
        for workflow_key in self.completed_workflows:
            workflow = self.completed_workflows[workflow_key]
            r.append({'workflow_name':workflow_key, 'status':'finished at step: '+str(workflow.step_num), 'step_num':workflow.step_num})
        return r
         
                 
    def get_names_of_available_workflows(self):
        # returns [{'workflow_name':'test.txt', 'status':'done'}, {'workflow_name':'glass_reception.txt', 'status':'done'}]
        import glob, os.path
        r = []
        for filepath in glob.glob( 'workflows/*.txt' ):
            r.append({'workflow_name':os.path.basename(filepath), 'status':'stopped'})
        return r
        
    
    def init_workflow(self, workflow_filename):
        pass
        
        
                
        
    def fd_step(self, workflow_name, input=None):
        import os.path, time
        if workflow_name not in self.active_workflows:
            print('starting workflow: '+workflow_name)
            self.active_workflows[workflow_name] = Workflow("test")
            self.active_workflows[workflow_name].load(os.path.join('workflows/',workflow_name))
            init_values = {}
            #init_values["1"] = 1
            #init_values["2"] = 2
            #init_values["3"] = 3
            #init_values["4"] = 4
            self.active_workflows[workflow_name].execute_one_step(workflow_name, init_values)
        else:
            if self.active_workflows[workflow_name].is_workflow_running(workflow_name): 
                
                print('fd_step() got input: '+str(input))
                
                # XMLRPC can't serialize None in {'Stack':None}
                if input != None:
                    self.push_data_into_current_step(workflow_name, 'actor_input', input)  
                
                #self.active_workflows[workflow_name].execute_one_step(workflow_name, [])
                self.active_workflows[workflow_name].execute_one_step(workflow_name, [])
            else:
                # workflow just finished, so move workflow from active_workflows to completed_workflows
                print('workflow '+workflow_name+' is finished')
                self.completed_workflows[workflow_name + 0*time.strftime(" %Y-%m-%d %H:%M:%S")] = self.active_workflows.pop(workflow_name)
                print(self.completed_workflows)
                        
        # {'1': 1, 'status': 'awaiting input', '3': 3, '2': 2, '4': 4}
        #print("## TRYING TO RETURN: ")
        rret = self.active_workflows[workflow_name].get_values_in_current_step(workflow_name)
        #import pprint
        #pprint.pprint(rret)
        return rret



    def execute_until_input_is_needed(self, workflow_name, input=None):
        import os.path, time
        if workflow_name not in self.active_workflows:
            print('starting workflow: '+workflow_name)
            self.active_workflows[workflow_name] = Workflow("test")
            self.active_workflows[workflow_name].load(os.path.join('workflows/',workflow_name))
            init_values = {}
            #init_values["1"] = 1
            #init_values["2"] = 2
            #init_values["3"] = 3
            #init_values["4"] = 4
            self.active_workflows[workflow_name].execute_until_input_is_needed(workflow_name, init_values)
        else:
            if self.active_workflows[workflow_name].is_workflow_running(workflow_name): 
                
                print('execute_until_input_is_needed() got input: '+str(input))
                
                # XMLRPC can't serialize None in {'Stack':None}
                if input != None:
                    self.push_data_into_current_step(workflow_name, 'actor_input', input)  
                
                #self.active_workflows[workflow_name].execute_until_input_is_needed(workflow_name, [])
                self.active_workflows[workflow_name].execute_until_input_is_needed(workflow_name, [])
            else:
                # workflow just finished, so move workflow from active_workflows to completed_workflows
                print('workflow '+workflow_name+' is finished')
                self.completed_workflows[workflow_name + 0*time.strftime(" %Y-%m-%d %H:%M:%S")] = self.active_workflows.pop(workflow_name)
                print(self.completed_workflows)
                        
        # {'1': 1, 'status': 'awaiting input', '3': 3, '2': 2, '4': 4}
        #print("## TRYING TO RETURN: ")
        rret = self.active_workflows[workflow_name].get_values_in_current_step(workflow_name)
        #import pprint
        #pprint.pprint(rret)
        return rret

     
   
# Comment out when running test cases (below) 
server = SimpleXMLRPCServer(("localhost", 8001))server.register_instance(WorkflowFunctions())server.serve_forever()


# ------------ tests ----------

# test server:  test Square component
#w = WorkflowFunctions()
#w.fd_step('processing_workflow.txt')
#w.fd_step('processing_workflow.txt', {'manuf_date':'xxxxxxxxx'})
#print(w.get_names_of_running_workflows())

# test server:  test reactivate_completed_workflow()
#w = WorkflowFunctions()
#w.fd_step('test.txt')
#w.fd_step('test.txt')
#w.fd_step('test.txt')
#w.fd_step('test.txt')
#print(w.get_list_of_completed_workflows())
#w.reactivate_completed_workflow(w.get_list_of_completed_workflows()[0]['workflow_name'], 2)
#print(w.get_names_of_running_workflows())

# test server:  test push_data_into_current_step()
#w = WorkflowFunctions()
#w.fd_step('stack_test.txt')
#w.fd_step('stack_test.txt', '67')
#w.fd_step('stack_test.txt', '97')
#w.fd_step('stack_test.txt')
#w.fd_step('stack_test.txt')

# test server:  test Square component
#w = WorkflowFunctions()
#w.fd_step('web_input.txt')
#print(w.get_names_of_running_workflows())
#w.fd_step('web_input.txt', [[2][8]])





